from rest_framework import response
from files.models import *
import datetime

from PIL import Image
import PyPDF2
import reportlab.pdfgen.canvas
import reportlab.lib.units
import uuid
from django.conf import settings
import openpyxl
import xlrd
import os
from django.http.response import StreamingHttpResponse
from reportlab.pdfgen import canvas
from reportlab.lib.units import cm, mm
from PyPDF2 import PdfFileWriter, PdfFileReader

from ac.models import LoginToken
from method.email import sendMail

TEMP_FILE = settings.MEDIA_ROOT + settings.DRAWING_PATH  # 列印导出excel的路径

SIGN_MODE_FIRST = 1  # 只簽首頁
SIGN_MODE_LAST = 2  # 只簽最後一頁
SIGN_MODE_ALL = 4  # 所有頁都簽核
SIGN_MODE_CUSTOMER = 8  # 用戶自定義
UNIT_CM = reportlab.lib.units.cm  # 釐米
UNIT_INCH = reportlab.lib.units.inch  # 英吋
UNIT_MM = reportlab.lib.units.mm  # 毫米
UNIT_PICA = reportlab.lib.units.pica
REMOTE_PATH = settings.MEDIA_ROOT + settings.DRAWING_PATH


class PdfSign(object):
    def __init__(
            self,
            path_pdf,
            path_image,
            sign_size_width,
            sign_size_height,
            sign_location_x,
            sign_location_y,
            size_unit=UNIT_MM,
            new_file=None,  # 新的pdf文件名稱
            sign_mode=SIGN_MODE_LAST,  # 只簽最後一頁
            custom_pages=None,
    ):
        """ 構造函數

        :param path_pdf: PDF文件路徑
        :param path_image: 簽名圖片路徑，一次只能传一个路径
        :param sign_size_width: 簽名寬度,单位：像素？
        :param sign_size_height:  簽名高度，单位：像素？
        :param sign_location_x:  簽名頁面位置X坐標(左下開始)
        :param sign_location_y:  簽名頁面位置Y坐標(左下開始)
        :param size_unit: 長度單位，定位簽名位置和寬高。默認為mm(毫米)
        :param new_file: 新的pdf文件名稱，如果為None，則會隨機生成一個文件名
        :param sign_mode: 簽核模式，默認為只簽最後一頁
        :param custom_pages: 如果指定簽核模式為custom，則需要指定一個list的頁碼信息
        :return:
        """
        self._pdf_path = path_pdf
        self._image_path = path_image
        self._sign_width = sign_size_width
        self._sign_height = sign_size_height
        self._location_x = sign_location_x
        self._location_y = sign_location_y
        self._size_unit = size_unit
        self._new_file = new_file
        if new_file is None:
            self._new_file = "%s.pdf" % uuid.uuid4().hex
        self._sign_file = REMOTE_PATH + "tmp.pdf.tmp"
        self._time_file = REMOTE_PATH + 'tim.pdf.tmp'
        self._form_file = REMOTE_PATH + "tmp.pdf1.tmp"
        self._sign_mode = sign_mode
        self._custom_page = custom_pages
        if custom_pages is None:
            self._custom_page = []
        elif isinstance(custom_pages, (list, tuple)):
            pass
        elif isinstance(custom_pages, str):
            self._custom_page = map(lambda x: int(x), custom_pages.split(','))
        elif isinstance(custom_pages, (int, float)):
            self._custom_page = [int(custom_pages)]
        else:
            raise TypeError(
                "expect custom_page is list or tuple, received '%s'" %
                custom_pages.__class__.__name__
            )

    @property
    def new_file(self):
        """
        :return: 新文件的名稱
        """
        return self._new_file

    def _create_sign(self):
        """ 創建一個簽名檔
        :return: 簽核當pdf
        """
        canvas = reportlab.pdfgen.canvas.Canvas(
            self._sign_file,
            pagesize=(
                self._sign_width * self._size_unit,
                self._sign_height * self._size_unit
            )
        )
        canvas.drawImage(
            self._image_path,
            self._location_x * self._size_unit,
            self._location_y * self._size_unit,
            width=self._sign_width * self._size_unit,
            height=self._sign_height * self._size_unit
        )

        canvas.setFillAlpha(0.3)
        canvas.save()
        try:
            return PyPDF2.PdfFileReader(open(self._sign_file, "rb"))
        finally:
            pass

    def _create_num(self):
        """ 創建一個簽名檔
        :return: 簽核當pdf
        """
        canvas = reportlab.pdfgen.canvas.Canvas(
            self._form_file,
            pagesize=(
                self._form_width * self._size_unit,
                self._form_height * self._size_unit
            )
        )
        canvas.drawImage(
            self._form_img,
            self._form_x * self._size_unit,
            self._form_y * self._size_unit,
            width=self._form_width * self._size_unit,
            height=self._form_height * self._size_unit
        )

        canvas.setFillAlpha(0.3)
        canvas.save()
        try:
            return PyPDF2.PdfFileReader(open(self._form_file, "rb"))
        finally:
            pass

    def pdf_info(self):
        """獲取pdf文件信息
        :returns pages,[{width:,height,}]
        """
        old_pdf = PyPDF2.PdfFileReader(open(self._pdf_path, "rb"))
        page_info = []
        pages = old_pdf.getNumPages()
        for index in range(pages):
            page = old_pdf.getPage(index)
            info = dict(
                index=index,
                width=page.mediaBox.getWidth(),
                height=page.mediaBox.getHeight(),
            )
            page_info.append(info)
        return pages, page_info

    def do_sign(self):
        """執行簽核
        :return None
        """
        old_pdf = PyPDF2.PdfFileReader(open(self._pdf_path, "rb"))
        old_pages = old_pdf.getNumPages()
        new_pdf = PyPDF2.PdfFileWriter()
        sign_page = self._create_sign().getPage(0)

        for index in range(old_pages):
            page = old_pdf.getPage(index)
            if self._sign_mode == SIGN_MODE_ALL:
                page.mergePage(sign_page)
            elif self._sign_mode == SIGN_MODE_FIRST:
                if index == 0:
                    page.mergePage(sign_page)
            elif self._sign_mode == SIGN_MODE_LAST:
                if index == (old_pages - 1):
                    page.mergePage(sign_page)
            elif self._sign_mode == SIGN_MODE_CUSTOMER:
                if index in self._custom_page:
                    page.mergePage(sign_page)  # 合并图片，将图片附在文档上
            else:
                raise ValueError("unknown sign mode '%s'" % self._sign_mode)
            if not page:
                continue

            new_pdf.addPage(page)
        with open(self._new_file, 'wb') as handler:
            new_pdf.write(handler)

    def __del__(self):
        if os.path.exists(self._sign_file):
            try:
                os.remove(self._sign_file)
            except WindowsError:
                pass


def gai_zhang(pdf, all_zhang, save_path):
    """
    给一个PDF文件最后一页盖章
    :param pdf: 该PDF文件的路径
    :param all_zhang: 盖章图片的路径集，用一个list保存
    :param save_path: 盖完章后保存PDF的路径
    :return:
    """

    def get_pdf(pdf, zhang, save_path, pic_width, location_x):
        pdf = PdfSign(path_pdf=pdf,
                      path_image=zhang,
                      sign_size_width=pic_width,
                      sign_size_height=1.0,
                      sign_location_x=location_x,
                      sign_location_y=1.0,
                      size_unit=UNIT_CM,
                      new_file=save_path,
                      sign_mode=SIGN_MODE_FIRST)
        return pdf

    one_pdf = get_pdf(pdf, all_zhang[0], save_path, 1, 1)  # 获取该PDF，用于查看该PDF长宽信息，以便后面定位盖章位置
    pdf_info = one_pdf.pdf_info()[-1][-1]
    size = Image.open(all_zhang[0]).size  # 获取第一张图片的分辨率，以便计算该图片的起始位
    if pdf_info['width'] > pdf_info['height']:
        location_x = 29.7 - 1 - (size[0] / size[1])  # 第一个章的起始X位
    else:
        location_x = 21 - 1 - (size[0] / size[1])
    rubbish_file_path = []
    for zhang in all_zhang:
        file_name = uuid.uuid4().hex
        save_path = save_path + file_name + '.pdf'
        rubbish_file_path.append(save_path)
        size = Image.open(zhang).size
        pic_width = size[0] / size[1]  # 图片宽度
        location_x = location_x - 0.2 - pic_width
        pdf_file = get_pdf(pdf, zhang, save_path, pic_width, location_x)
        pdf_file.do_sign()
        pdf = save_path
    for i in rubbish_file_path[0:-1]:
        os.remove(i)
    return save_path


def Response(*args, **kwargs):
    re = response.Response(*args, **kwargs)
    re['Access-Control-Allow-Origin'] = '*'
    # re["Access-Control-Allow-Methods"] = "POST, GET, OPTIONS,DELETE,PUT"
    re["Access-Control-Allow-Credentials"] = "true"
    re['Content-Type'] = 'application/json'
    return re


def seal_num():
    count = TbSeal.objects.all().count()
    if count == 0:
        s_num = "S0001"
    else:
        s_no = TbSeal.objects.values("seal_no").order_by("-id")[0]["seal_no"]
        nu = int(s_no.replace("S", "20171212")) + 1
        s_num = str(nu).replace("20171212", "S")
    return s_num


def change_status(workflowrecord_id, pdf_list):
    """
    1,需要把工程阶段或者客户阶段的签核完成的图纸文件列表更新到tb_drawing_file里sign_filepath,改变状态
    workflowrecord_id:签核履历id,
    pdf_list : 签核完文件路径。

    :return:
    """
    project_id = TbApplyform.objects.filter(wrecord=workflowrecord_id).values_list("project_id", flat=True)
    customer_id = TbApplyform.objects.filter(wrecord=workflowrecord_id).values_list("customer_id", flat=True)

    if project_id[0]:
        # fujian = TbDrawingFile.objects.filter(project_id=project_id, file_type=1).values_list("id", "file_path")
        # if fujian:
        #     for tup in fujian:
        #         TbDrawingFile.objects.filter(id=tup[0]).update(sign_filepath=tup[1])

        copy_id = TbProjectPaper.objects.filter(id=project_id).values_list("id_copy", flat=1)[0]
        TbProjectPaper.objects.filter(id_copy=copy_id).update(current=0, enabled=0)
        TbProjectPaper.objects.filter(id=project_id).update(p_confirm=2, current=1, enabled=1)
        # id_list = TbDrawingFile.objects.filter(project_id=project_id, file_type=0).values_list("id", flat=1)
        # for i, file_id in enumerate(id_list):
        #     TbDrawingFile.objects.filter(id=file_id).update(sign_filepath=pdf_list[i])

    elif customer_id[0]:
        # fujian = TbDrawingFile.objects.filter(customer_id=customer_id, file_type=1).values_list("id", "file_path")
        # if fujian:
        #     for tup in fujian:
        #         TbDrawingFile.objects.filter(id=tup[0]).update(sign_filepath=tup[1])
        copy_id = TbCustomerPaper.objects.filter(id=customer_id).values_list("copy_id", flat=1)[0]
        TbCustomerPaper.objects.filter(copy_id=copy_id).update(current=0, enabled=0)
        TbCustomerPaper.objects.filter(id=customer_id[0]).update(c_confirm=2, current=1, enabled=1)
        # id_list = TbDrawingFile.objects.filter(customer_id=customer_id, file_type=0).values_list("id", flat=True)
        # for i, file_id in enumerate(id_list):
        #     TbDrawingFile.objects.filter(id=file_id).update(sign_filepath=pdf_list[i])

    return True


def reject_status(workflowrecord_id):
    """
    驳回

    :return:
    """
    project_id = TbApplyform.objects.filter(wrecord=workflowrecord_id).values_list("project_id", flat=True)
    customer_id = TbApplyform.objects.filter(wrecord=workflowrecord_id).values_list("customer_id", flat=True)

    if project_id[0]:

        copy_id = TbProjectPaper.objects.filter(id=project_id).values_list("id_copy", flat=1)[0]
        # TbProjectPaper.objects.filter(id_copy=copy_id).update(current=0, enabled=0)
        TbProjectPaper.objects.filter(id=project_id).update(p_confirm=-1)

    elif customer_id[0]:

        copy_id = TbCustomerPaper.objects.filter(id=customer_id).values_list("copy_id", flat=1)[0]
        # TbCustomerPaper.objects.filter(copy_id=copy_id).update(current=0, enabled=0)
        TbCustomerPaper.objects.filter(id=customer_id[0]).update(c_confirm=-1)

    return True


def print_download(data, path):
    wb = openpyxl.Workbook()  # 新建一个工作簿
    ws = wb.active  # 获取sheet
    ws.title = '列印信息'  # 设置sheet名为工段名
    ws['A1'] = 'SUPER TOOL'
    ws['A2'] = "工程文件/圖面分發及回收記錄表"
    ws.cell(row=1, column=1).font = openpyxl.styles.fonts.Font(sz=18)  # 设置字号
    ws.cell(row=1, column=1).alignment = openpyxl.styles.alignment.Alignment(
        horizontal='center', vertical='center')  # 设置样式
    ws.merge_cells(start_row=1, start_column=1, end_row=1, end_column=15)  # 融合cell

    ws['A3'] = '序號'
    ws['B3'] = 'ECN編號'
    ws["C3"] = "產品類別"
    ws['D3'] = '產品階段'
    ws['E3'] = '版次'
    ws['F3'] = '刀具規格'
    ws['G3'] = '專案名稱'
    ws['H3'] = '文件名稱'
    ws['I3'] = '分發單位'
    ws['J3'] = '申請份數'
    ws['K3'] = '狀態'
    ws['L3'] = '申請人'
    ws['M3'] = '申請日期'
    ws['N3'] = '回收人'
    ws['O3'] = '回收日期'
    ws["P3"] = '回收份數'
    ws["Q3"] = '簽名'
    data_order = ["ecn_no", "product_type", "product_stage", "version", "custters_spec", "case_name", "file_name",
                  "dispensing",
                  "print_no", "status", "sponsor", "create_time", "signer", "modify_time", "recycling_no"]
    start_row = 4  # 数据起始行
    now = datetime.datetime.now().strftime('%Y%m%d%H%M%S')
    for i, one_data in enumerate(data):  # 循环每一行

        for key, value in one_data.items():  # 遍历每一列
            if key in data_order:
                ws.cell(row=start_row, column=1).value = i + 1
                ws.cell(row=start_row, column=data_order.index(key) + 2).value = value
        start_row = start_row + 1

    wb.save(os.path.join(TEMP_FILE, now + '.xlsx'))  # 保存文件，待下载后删除

    # def file_iterator(file_name, chunk_size=512):
    #     with open(file_name, 'rb') as f:
    #         while True:
    #             c = f.read(chunk_size)
    #             if c:
    #                 yield c
    #             else:
    #                 break
    #
    #     os.remove(os.path.join(TEMP_FILE, 'temp.xlsx'))
    #
    # response = StreamingHttpResponse(file_iterator(os.path.join(TEMP_FILE, 'temp.xlsx')))
    # response['Content-Type'] = 'application/octet-stream'
    # response['Access-Control-Allow-Origin'] = '*'
    # response['Content-Disposition'] = 'attachment;filename="{}{}.xlsx"'.format('printing',
    #                                                                            datetime.datetime.now().strftime(
    #                                                                                '%Y%m%d%H%M%S'))
    # return response
    return settings.DRAWING_PATH + now + ".xlsx"


####印章pdf
def create_watermark(f_jpg, f_pdf, x, y, w, h):
    w_pdf = 20 * cm
    h_pdf = 20 * cm
    c = canvas.Canvas(f_pdf, pagesize=(w_pdf, h_pdf))
    c.setFillAlpha(0.3)  # 设置透明度
    c.drawImage(f_jpg, x * mm, y * mm, w * mm, h * mm)  # 这里的单位是物理尺寸
    c.save()
    return f_pdf


def add_watermark(pdf_file_in, pdf_file_mark, pdf_file_out):
    pdf_output = PdfFileWriter()
    input_stream = open(pdf_file_in, 'rb')
    pdf_input = PdfFileReader(input_stream)

    # PDF文件被加密了
    if pdf_input.getIsEncrypted():
        print('该PDF文件被加密了.')
        # 尝试用空密码解密
        try:
            pdf_input.decrypt('')
        except Exception as e:
            print('尝试用空密码解密失败.')
            return False
        else:
            print('用空密码解密成功.')
    # 获取PDF文件的页数
    pageNum = pdf_input.getNumPages()
    # 读入水印pdf文件
    pdf_watermark = PdfFileReader(open(pdf_file_mark, 'rb'))
    # 给每一页打水印
    for i in range(pageNum):
        page = pdf_input.getPage(i)
        page.mergePage(pdf_watermark.getPage(0))
        page.compressContentStreams()  # 压缩内容
        pdf_output.addPage(page)
    outputStream = open(pdf_file_out, "wb")
    pdf_output.write(outputStream)
    return pdf_file_out


def seal_pdf(file_in, seal_path):
    # file_in = "D:/1590.pdf"
    # seal_path = "D:/222.jpg"
    file_path = []
    # del_file= []
    for i, seal in enumerate(seal_path):
        x, y = 150, 35

        # x = 15 - x * i
        y = 180 - y * i
        file_name = settings.MEDIA_ROOT + settings.DRAWING_PATH + str(uuid.uuid4()) + ".pdf"
        f_pdf = create_watermark(seal, file_name, x, y, 50, 25)
        file_out = settings.MEDIA_ROOT + settings.DRAWING_PATH + str(uuid.uuid4()) + ".pdf"

        add_watermark(file_in, f_pdf, file_out)
        file_in = file_out
        file_path.append(file_name)
        file_path.append(file_in)
        # return file_in
    for i in range(len(file_path) - 1):
        os.remove(file_path[i])
    return file_path[-1]


def parse(path):
    data = xlrd.open_workbook(path, 'rb')
    table = data.sheet_by_index(0)
    excel_list = []
    # query = """INSERT INTO tb_large_org( org_code,first_org_name) VALUES (%s,%s)"""
    for r in range(1, table.nrows):
        month = table.cell(r, 1).value
        amout = table.cell(r, 2).value
        excel_list.append({"predict": amout, "month": month})
    os.remove(path)
    return excel_list


def mailtototot(username, title, type, sql, url,forms):
    user22222 = User.objects.filter(username=username)[0]
    to = LoginToken.objects.filter(user_id=user22222.id).order_by('-end_date')
    if to:
        to = LoginToken.objects.filter(id=to[0].id).update(
            end_date=datetime.datetime.now() + datetime.timedelta(days=8))
    else:
        token = str(uuid.uuid4())
        to = LoginToken.objects.create(user_id=user22222.username, token=token,
                                       end_date=datetime.datetime.now() + datetime.timedelta(days=8))
    sendMail(user22222.email, settings.APPROVAL_SUB[2].format(title, user22222.last_name, type),
             settings.APPROVAL_CONTENT[2].format(user22222.last_name, type + sql,
                                                 settings.EMAIL_TEMPLATE["HOST"] + settings.WEB_HRAD[1].format(url,forms,
                                                     to.token)))
    # sendMail(user22222.email,head,content)


if __name__ == "__main__":
    change_status(631, "123")
